package com.zhn.evsi.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhn.evsi.client.SkillClient;
import com.zhn.evsi.common.RedisCache;
import com.zhn.evsi.domain.dto.evsi.*;
import com.zhn.evsi.domain.dto.evsi.character.EvsiCharacterPublicInfoDTO;
import com.zhn.evsi.domain.entity.evsi.EvsiCharacterSkills;
import com.zhn.evsi.domain.entity.evsi.EvsiIcons;
import com.zhn.evsi.domain.entity.evsi.EvsiInvtypes;
import com.zhn.evsi.domain.vo.EvsiCharacterSkillListPIE;
import com.zhn.evsi.interceptor.CharacterInterceptor;
import com.zhn.evsi.mapper.EvsiCharacterSkillsMapper;
import com.zhn.evsi.service.IEvsiCharacterSkillsService;
import com.zhn.evsi.service.IEvsiIconsService;
import com.zhn.evsi.service.IEvsiInvtypesService;
import com.zhn.evsi.service.IEvsiMarketgroupsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.NumberFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class EvsiCharacterSkillsServiceImpl extends ServiceImpl<EvsiCharacterSkillsMapper, EvsiCharacterSkills> implements IEvsiCharacterSkillsService {

    @Value("${eve.jitaRegionLimit}")
    private String regionLimit;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private SkillClient skillClient;
    @Autowired
    private IEvsiIconsService iconsService;
    @Autowired
    private IEvsiInvtypesService invtypesService;
    @Autowired
    private IEvsiMarketgroupsService marketgroupsService;
    @Autowired
    private CharacterInterceptor characterInterceptor;

    /**
     * 获取当前训练队列
     * <p>
     * TODO redis暂存2h优化
     */
    @Override
    public Map<String, Object> skillQueue() {
        // 配置防止科学计数
        NumberFormat instance = NumberFormat.getInstance();
        instance.setGroupingUsed(false);
        EvsiCharacterPublicInfoDTO characters = characterInterceptor.getCharacters(null);

        Map<String, Object> map = redisCache.getCacheObject("Character:SkillQueue:" + characters.getCharacters());
        if (ObjectUtil.isNull(map)) {
            map = new LinkedHashMap<>();
            List<EvsiCharacterSkillQueueDTO> evsiCharacterSkillQueueDTOList = new ArrayList<>();
            List<JSONObject> jsonObjectList = skillClient.skillQueue(characters.getCharacters());
            jsonObjectList.forEach(v -> {
                EvsiCharacterSkillQueueDTO evsiCharacterSkillQueueDTO = JSON.toJavaObject(v, EvsiCharacterSkillQueueDTO.class);
                evsiCharacterSkillQueueDTOList.add(evsiCharacterSkillQueueDTO);
            });
            evsiCharacterSkillQueueDTOList.forEach(v -> {
                v.setSkill_name(invtypesService.getOne(new LambdaQueryWrapper<EvsiInvtypes>().eq(EvsiInvtypes::getTypeId, v.getSkill_id())).getTypeName());
                int trainSp = v.getLevel_end_sp() - v.getTraining_start_sp(); // 获取每个技能需要的技能点
                v.setTraining_sp(trainSp);
            });
            Integer trainingSp = evsiCharacterSkillQueueDTOList.stream().map(EvsiCharacterSkillQueueDTO::getTraining_sp).reduce(Integer::sum).orElse(0);
            // 判断当前技能点数，然后进行脑浆有效判断
            // 获取当前技能点数以及未使用的技能点数
            JSONObject skills = skillClient.skills(characters.getCharacters());
            Integer totalSp = (Integer) skills.get("total_sp");
            Integer unallocatedSp = (Integer) skills.get("unallocated_sp");
            // 获取需要训练的技能点数以及脑浆数量和脑浆价格
            int trainingSps = trainingSp - unallocatedSp;
            int injector = trainingSps / 400000 + 1;
            Integer[] injectors = new Integer[]{40520};
            List<EvsiMarketStatDTO> evsiMarketStatDTOS = marketgroupsService.marketStat(injectors, regionLimit);
            Double injectorsSellMin = evsiMarketStatDTOS.get(0).getSell().getMin();
            // 获取训练完成时间
            EvsiCharacterSkillQueueDTO evsiCharacterSkillQueueDTO = evsiCharacterSkillQueueDTOList.get(evsiCharacterSkillQueueDTOList.size() - 1);
            // 获取每分钟新增多少sp
            Date now = new Date(); // 当前时间
            Date finishDate = evsiCharacterSkillQueueDTO.getFinish_date();// 训练结束时间
            long time = (finishDate.getTime() - now.getTime()) / 1000 / 60;
            double minSps = (double) (trainingSps / time);
            map.put("totalSp", totalSp); // 当前技能点数
            map.put("unallocatedSp", unallocatedSp); // 未使用技能点数
            map.put("trainingFinishDate", evsiCharacterSkillQueueDTO.getFinish_date());
            map.put("trainingSps", trainingSps); // 训练需要的技能点数量
            map.put("minSps", minSps); // 每分钟新增多少sp
            map.put("injector", injector); // 需要的注射器数量
            map.put("injectorPrice", instance.format(injectorsSellMin)); //脑浆价格
            map.put("injectorSellMin", instance.format(injector * injectorsSellMin)); // 需要的脑浆总价格
            map.put("skillQueue", evsiCharacterSkillQueueDTOList); // 当前训练队列的技能

            redisCache.setCacheObject("Character:SkillQueue:" + characters.getCharacters(), map, 2, TimeUnit.HOURS);
        }
        return map;
    }

    /**
     * 获取技能列表
     * <p>
     * TODO redis暂存2h 优化
     */
    @Override
    public Map<String, Object> skillList() {

        // 初始化参数
        AtomicReference<Integer> oneNum = new AtomicReference<>(0);
        AtomicReference<Integer> twoNum = new AtomicReference<>(0);
        AtomicReference<Integer> thrNum = new AtomicReference<>(0);
        AtomicReference<Integer> fourNum = new AtomicReference<>(0);
        AtomicReference<Integer> fiveNum = new AtomicReference<>(0);

        List<EvsiCharacterSkillListPIE> characterSkillListPIE = new ArrayList<>();

        EvsiCharacterPublicInfoDTO characters = characterInterceptor.getCharacters(null);
        Map<String, Object> map = redisCache.getCacheObject("Character:SkillList:" + characters.getCharacters());
        if (ObjectUtil.isNull(map)) {
            map = new HashMap<>();
            EvsiCharacterSkillsDTO characterSkillsDTO = new EvsiCharacterSkillsDTO();
            JSONObject skills = skillClient.skills(characters.getCharacters());
            characterSkillsDTO = JSON.toJavaObject(skills, EvsiCharacterSkillsDTO.class);
            System.out.println(characterSkillsDTO.getSkills().size());
            characterSkillsDTO.getSkills().forEach(v -> {
                EvsiInvtypes skillInvtype = invtypesService.getOne(new LambdaQueryWrapper<EvsiInvtypes>().eq(EvsiInvtypes::getTypeId, v.getSkill_id()));
                v.setSkill_name(skillInvtype.getTypeName()); // 技能名称
                v.setSkill_group(skillInvtype.getGroupId()); // 技能分组id
                // 通过图标id查询出来地址
                String iconFile = iconsService.getOne(new LambdaQueryWrapper<EvsiIcons>().eq(EvsiIcons::getIconId, skillInvtype.getIconId())).getIconFile();
                v.setSkill_icon(skillInvtype.getIconId()); // 技能图标id
                v.setSkill_file(iconFile);

                switch (v.getActive_skill_level()) {
                    case 1:
                        oneNum.getAndSet(oneNum.get() + 1);
                        break;
                    case 2:
                        twoNum.getAndSet(twoNum.get() + 1);
                        break;
                    case 3:
                        thrNum.getAndSet(thrNum.get() + 1);
                        break;
                    case 4:
                        fourNum.getAndSet(fourNum.get() + 1);
                        break;
                    case 5:
                        fiveNum.getAndSet(fiveNum.get() + 1);
                        break;
                }
            });
            // 生成饼状图数据
            characterSkillListPIE.add(EvsiCharacterSkillListPIE.builder().name("Ⅰ").value(oneNum.get()).build());
            characterSkillListPIE.add(EvsiCharacterSkillListPIE.builder().name("Ⅱ").value(twoNum.get()).build());
            characterSkillListPIE.add(EvsiCharacterSkillListPIE.builder().name("Ⅲ").value(thrNum.get()).build());
            characterSkillListPIE.add(EvsiCharacterSkillListPIE.builder().name("Ⅳ").value(fourNum.get()).build());
            characterSkillListPIE.add(EvsiCharacterSkillListPIE.builder().name("Ⅴ").value(fiveNum.get()).build());

            map.put("pie", characterSkillListPIE);
            map.put("skillList", characterSkillsDTO);

            redisCache.setCacheObject("Character:SkillList:" + characters.getCharacters(), map, 2, TimeUnit.HOURS);
        }


        return map;
    }

    /**
     * 技能All
     */
    @Override
    public List<EvsiCharacterSkillAllDTO> skillAll() {
        return this.baseMapper.skillAll();
    }

    /**
     * 根据舰船获取技能信息
     *
     * @param TypeId - 舰船typeId
     * @param level  - 等级
     */
    @Override
    public List<EvsiCharacterSkillCustomizationDTO> customization(Integer TypeId, Integer level) {
        List<EvsiCharacterSkillCustomizationDTO> characterSkillCustomizations = redisCache.getCacheObject("customization:" + TypeId + ":" + level + ":");
        if (characterSkillCustomizations == null) {
            characterSkillCustomizations = this.baseMapper.customization(TypeId, level);
            redisCache.setCacheObject("customization:" + TypeId + ":" + level + ":", characterSkillCustomizations, 5, TimeUnit.DAYS);
        }
        return characterSkillCustomizations;
    }

    /**
     * 获取角色属性点
     */
    @Override
    public EvsiCharacterAttributesDTO attributes() {
        EvsiCharacterPublicInfoDTO characters = characterInterceptor.getCharacters(null);
        EvsiCharacterAttributesDTO attributes = skillClient.attributes(characters.getCharacters());
        return attributes;
    }

    /**
     * 技能规划
     */
    @Override
    public void skillPlan() {
        // 好困啊，好困
    }


}
